package com.htgd.gardenexpo.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.htgd.gardenexpo.dao.*;
import com.htgd.gardenexpo.dto.GeConPlantSeatDTO;
import com.htgd.gardenexpo.dto.GeConTheaterPlanDTO;
import com.htgd.gardenexpo.entity.*;
import com.htgd.gardenexpo.page.PageBase;
import com.htgd.gardenexpo.page.PlanQuery;
import com.htgd.gardenexpo.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.htgd.gardenexpo.utils.TokenUtil;
import com.htgd.gardenexpo.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.htgd.gardenexpo.utils.DateUtils.addMinutes;

/**
 * <p>
 * 放映计划 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-09-09
 */
@Service
public class GeConTheaterPlanServiceImpl extends ServiceImpl<GeConTheaterPlanMapper, GeConTheaterPlan> implements GeConTheaterPlanService {

    @Autowired
    private GeConTheaterPlanMapper geConTheaterPlanMapper;

    @Autowired
    private GeConTheaterPlanMovieMapper geConTheaterPlanMovieMapper;

    @Autowired
    private GeBaseDictService geBaseDictService;

    @Autowired
    private GeConTheaterTimeMapper geConTheaterTimeMapper;

    @Autowired
    private WxUserTheaterTicketMapper wxUserTheaterTicketMapper;

    @Autowired
    private GeConTheaterSeatMapper geConTheaterSeatMapper;

    @Autowired
    private GeBaseUserService geBaseUserService;

    @Autowired
    private GeConTheaterPlanMovieService geConTheaterPlanMovieService;

    @Autowired
    private GeConTheaterSeatService geConTheaterSeatService;

    @Autowired
    private GeConTheaterSeatTimeMapper geConTheaterSeatTimeMapper;

    @Autowired
    private GeConTheaterPlanService geConTheaterPlanService;

    @Autowired
    private IGeConTheaterTimeService geConTheaterTimeService;

    @Autowired
    private GeConTheaterPlanReserveMapper geConTheaterPlanReserveMapper;

    @Autowired
    private GeConTheaterMovieActorMapper geConTheaterMovieActorMapper;

    @Autowired
    private GeConTheaterMovieMapper geConTheaterMovieMapper;

    @Autowired
    private IWxUserTheaterTicketService wxUserTheaterTicketService;


    @Override
    public PageInfo<GeConTheaterPlanVO> pageList(PlanQuery planQuery) {
        PageHelper.startPage(planQuery.getPageNum(), planQuery.getPageSize());
        List<GeConTheaterPlanVO> list= geConTheaterPlanMapper.pageList(planQuery);
        for (GeConTheaterPlanVO geConTheaterPlanVO : list) {
            if(geConTheaterPlanVO.getStatus()!=null){
                geConTheaterPlanVO.setStatusText(geBaseDictService.getStatusText(String.valueOf(geConTheaterPlanVO.getStatus())));
            }

            if(geConTheaterPlanVO.getIsTop()!=null){
                geConTheaterPlanVO.setIsTopText(geBaseDictService.getTopText(String.valueOf(geConTheaterPlanVO.getIsTop())));
            }
            //
            QueryWrapper<GeConTheaterPlanMovie> queryWrapper =new QueryWrapper<>();
            queryWrapper.eq("plan_id",geConTheaterPlanVO.getId());
            List<GeConTheaterPlanMovie> geConTheaterPlanMovies = geConTheaterPlanMovieMapper.selectList(queryWrapper);
            List<String> movieIds = new ArrayList<>();
            for (GeConTheaterPlanMovie geConTheaterPlanMovie : geConTheaterPlanMovies) {
                movieIds.add(geConTheaterPlanMovie.getMovieId());
            }
            geConTheaterPlanVO.setMovieIds(movieIds);
        }
        return new PageInfo<>(list);
    }

    @Override
    public List<GeConTheaterPlan> getEffectiveList() {
        return lambdaQuery().eq(GeConTheaterPlan::getEffectiveStatus,1)
                .list();
    }

    @Override
    public TheaterHomePageVO getTheaterHomePage(HttpServletRequest request) {
        String accessToken = request.getHeader("Access_token");
        TheaterHomePageVO theaterHomePageVO = new TheaterHomePageVO();
        List<HomePageTicketList> homePageTicketLists  = geConTheaterPlanMapper.getTheaterHomePage();
        String openId = TokenUtil.getUsernameFromToken(accessToken);
        String localDateTime = null;
        for (HomePageTicketList homePageTicketList : homePageTicketLists) {
            //类型字典
            if(homePageTicketList.getType()!=null){
                String typeText = "";
                String[] split = homePageTicketList.getType().split(",");
                for (String s : split) {
                    String type_movie = geBaseDictService.getTextByCodeAndValue("type_movie", s);
                    typeText = typeText + type_movie+"/";

                }
                homePageTicketList.setTypeText(typeText.substring(0,typeText.length()-1));
            }
            //演出时间
            GeConTheaterTime geConTheaterTime = geConTheaterTimeMapper.selectById(1);
            homePageTicketList.setShowTime(LocalDate.now()+" "+geConTheaterTime.getShowTime());
            localDateTime = LocalDate.now()+" "+geConTheaterTime.getShowTime();
        }
        theaterHomePageVO.setHomePageTicketLists(homePageTicketLists);
        GeConTheaterSeat geConTheaterSeat = geConTheaterSeatMapper.selectOne(new LambdaQueryWrapper<GeConTheaterSeat>().last("limit 1"));
        JSONArray jsonArray = JSONArray.parseArray(geConTheaterSeat.getSeat());
        //座位总数
        int num = jsonArray.size();
        //已选座位数
        int selectedSeats = 0;
        List<GeConTheaterSeatTime> list = geConTheaterSeatTimeMapper.selectList(new LambdaQueryWrapper<GeConTheaterSeatTime>()
        .eq(GeConTheaterSeatTime::getShowTime,localDateTime));
        if(!list.isEmpty()){
            for(GeConTheaterSeatTime seatTime:list){
                selectedSeats = selectedSeats+JSONArray.parseArray(seatTime.getSeat()).size();
            }
        }
        GeConTheaterSeatTime geConTheaterSeatTime1 = geConTheaterSeatTimeMapper.selectOne(new LambdaQueryWrapper<GeConTheaterSeatTime>()
                .eq(GeConTheaterSeatTime::getShowTime,localDateTime)
                .eq(GeConTheaterSeatTime::getOpenId,openId));
        if(Objects.nonNull(geConTheaterSeatTime1)){
            theaterHomePageVO.setSeatStatus("1");
        }else{
            boolean flag = false;
            for (int j = 0; j < jsonArray.size(); j++) {
                String element = jsonArray.getString(j);
                JSONObject jsonObject = JSONObject.parseObject(element);
                String status = (String)jsonObject.get("status");
                if(Objects.equals(status,"0")){
                    flag = true;
                    break;
                }
            }
            if(flag){
                theaterHomePageVO.setSeatStatus("0");
            }else{
                theaterHomePageVO.setSeatStatus("1");
            }
        }
        theaterHomePageVO.setSelectedSeats(selectedSeats);
        theaterHomePageVO.setRemainingSeats(num-selectedSeats);
        theaterHomePageVO.setSeats(jsonArray);
        return theaterHomePageVO;
    }

    @Override
    public  PageInfo<TheaterTicketListVO> getVotingInformation(PageBase pageBase, String openId) {
        PageHelper.startPage(pageBase.getPageNum(), pageBase.getPageSize());
        List<TheaterTicketListVO> list = geConTheaterPlanMapper.getVotingInformation();
        for (TheaterTicketListVO ticketListVO : list) {
            //类型字典
            if(ticketListVO.getType()!=null){
                String typeText = "";
                String[] split = ticketListVO.getType().split(",");
                for (String s : split) {
                    String type_movie = geBaseDictService.getTextByCodeAndValue("type_movie", s);
                    typeText = typeText + type_movie+"/";

                }
                ticketListVO.setTypeText(typeText.substring(0,typeText.length()-1));
            }
            //是否投过票
           WxUserTheaterTicket wxUserTheaterTicket = wxUserTheaterTicketMapper.isVote(openId,ticketListVO.getId(),ticketListVO.getPlanId());
            if(wxUserTheaterTicket!=null){
                ticketListVO.setFlag(true);
            }else {
                ticketListVO.setFlag(false);
            }
        }
        return new PageInfo<>(list);
    }

    @Transactional
    @Override
    public CommonResult add(GeConTheaterPlanDTO geConTheaterPlanDTO, String phone) {
        //判断是否有重复的
        List<GeConTheaterPlan> effective =  lambdaQuery().eq(GeConTheaterPlan::getEffectiveStatus,1)
                .list();
        for (GeConTheaterPlan conTheaterPlan : effective) {
            LocalDate startTime = conTheaterPlan.getStartTime();
            if(geConTheaterPlanDTO.getStartTime().equals(startTime)){
                return CommonResult.error("有日期重叠的生效计划");
            }
        }
        //判断是否类型和电影数量对着
        if("1".equals(geConTheaterPlanDTO.getType())){
            if(geConTheaterPlanDTO.getMovieIds().size()>1){
                return CommonResult.error("放映只能选择1部电影");
            }
        }
        //一周只能建一个点映
        if("2".equals(geConTheaterPlanDTO.getType())){
            List<GeConTheaterPlanVO> geConTheaterPlanVOS = geConTheaterPlanMapper.getWeeKDianYing();
            if(geConTheaterPlanVOS.size()>1){
                return CommonResult.error("本周已经有点映了,无法创建");
            }
        }

        //获取创建人
        String username = geBaseUserService.getUserByPhone(phone).get(0).getUsername();
        //复制数据
        GeConTheaterPlan geConTheaterPlan = new GeConTheaterPlan();
        BeanUtils.copyProperties(geConTheaterPlanDTO,geConTheaterPlan);
        geConTheaterPlan.setCreateUser(username);
        geConTheaterPlan.setStatus(4);
        geConTheaterPlan.setEffectiveStatus(0);
        geConTheaterPlan.setNum(geConTheaterPlanDTO.getMovieIds().size());
        geConTheaterPlanMapper.insert(geConTheaterPlan);
        //电影进入
        List<String> movieIds = geConTheaterPlanDTO.getMovieIds();
        for (String movieId : movieIds) {
            GeConTheaterPlanMovie geConTheaterPlanMovie = new GeConTheaterPlanMovie();
            geConTheaterPlanMovie.setPlanId(geConTheaterPlan.getId());
            geConTheaterPlanMovie.setMovieId(movieId);
            geConTheaterPlanMovie.setTickets(0);
            geConTheaterPlanMovieService.save(geConTheaterPlanMovie);
        }
        return CommonResult.success("添加成功");
    }

    @Transactional
    @Override
    public synchronized void updateSeats(GeConPlantSeatDTO geConPlantSeat, HttpServletRequest request) throws Exception {
        String accessToken = request.getHeader("Access_token");
        String openId = TokenUtil.getUsernameFromToken(accessToken);
        //获取自己今天场次的座位预约信息
        GeConTheaterSeatTime geConTheaterSeatTime1 = geConTheaterSeatTimeMapper.selectOne(new LambdaQueryWrapper<GeConTheaterSeatTime>()
            .eq(GeConTheaterSeatTime::getShowTime,geConPlantSeat.getShowTime())
            .eq(GeConTheaterSeatTime::getOpenId,openId));
        if(Objects.nonNull(geConTheaterSeatTime1)){
            throw new Exception();
        }
        //获取整个座位表
        GeConTheaterSeat geConTheaterSeat = geConTheaterSeatMapper.selectOne(new LambdaQueryWrapper<GeConTheaterSeat>().last("limit 1"));
        JSONArray jsonArray = JSONArray.parseArray(geConTheaterSeat.getSeat());
        List<GeConTheaterSeatTime> timeList = geConTheaterSeatTimeMapper.selectList(new LambdaQueryWrapper<GeConTheaterSeatTime>()
                .eq(GeConTheaterSeatTime::getShowTime,geConPlantSeat.getShowTime()));
//        if(!timeList.isEmpty()){
//            timeList.stream().forEach(item->{
//                jsonArray.addAll(JSONArray.parseArray(item.getSeat()));
//            });
//        }
        JSONArray seatList = new JSONArray();
        // 遍历JSONArray中的元素
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject seat = new JSONObject();
            // 获取每个索引对应的元素
            String element = jsonArray.getString(i);
//            System.out.println("Element at index " + i + ": " + element);
            JSONObject jsonObject = JSONObject.parseObject(element);
            String value = (String)jsonObject.get("value");
            String status = (String)jsonObject.get("status");
//            System.out.println(value);
//            System.out.println(status);
//            System.out.println("----------------------");
            JSONArray jsonArrayJ = JSONArray.parseArray(geConPlantSeat.getSeats().toJSONString());
            for (int j = 0; j < jsonArrayJ.size(); j++) {
                String elementJ = jsonArrayJ.getString(j);
                JSONObject jsonObjectJ = JSONObject.parseObject(elementJ);
                String valueJ = (String)jsonObjectJ.get("value");
                if(Objects.equals(value,valueJ)){
                    status = ((String)jsonObjectJ.get("status"));
                    break;
                }
            }
            seat.put("value",value);
//            System.out.println(status);
            seat.put("status",status);
            seatList.add(seat);
        }
//        System.out.println(JSONObject.toJSONString(seatList));
        GeConTheaterSeat geConTheaterSeat1 = new GeConTheaterSeat();
        geConTheaterSeat1.setId(1);
        geConTheaterSeat1.setSeat(seatList.toJSONString());
        geConTheaterSeat1.setUpdateTime(LocalDateTime.now());
        geConTheaterSeatService.updateById(geConTheaterSeat1);
        GeConTheaterSeatTime geConTheaterSeatTime = new GeConTheaterSeatTime();
        geConTheaterSeatTime.setCreateTime(LocalDateTime.now());
        geConTheaterSeatTime.setShowTime(geConPlantSeat.getShowTime());
        geConTheaterSeatTime.setSeat(JSONArray.toJSONString(geConPlantSeat.getSeats()));
        geConTheaterSeatTime.setOpenId(openId);
        geConTheaterSeatTime.setPlanId(geConPlantSeat.getPlanId());
        geConTheaterSeatTimeMapper.insert(geConTheaterSeatTime);
    }

    @Override
    public CommonResult<TheaterNumsVO> getAttendanceAndMovieTicketNums(String date, Integer pageNum, Integer pageSize) {
        TheaterNumsVO result = new TheaterNumsVO();

        DateTimeFormatter formatter =  DateTimeFormatter.ofPattern("yyyy-MM-dd");
        //不传，默认当天
        if(date==null||"".equals(date)){
            date = LocalDateTime.now().format(formatter);
        }

        //上座率
        int nums = 0;
        List<String> selectArr = new ArrayList<>();
        List<GeConTheaterSeatTime> geConTheaterSeatTimes = geConTheaterSeatTimeMapper.getByDate(date);
        for (GeConTheaterSeatTime geConTheaterSeatTime : geConTheaterSeatTimes) {
            JSONArray jsonArray = JSONArray.parseArray(geConTheaterSeatTime.getSeat());
            for (Object js : jsonArray) {
                String string = js.toString();
                JSONObject jsonObject = JSONObject.parseObject(string);
                String value = jsonObject.getString("value");
                selectArr.add(value);
            }
            nums = nums +jsonArray.size();
        }
        double rate = (double) nums / 68;
        String occupancyRate = String.format("%.2f", rate * 100) + "%";  // 保留两位小数并加上 "%"

        GeConTheaterSeat geConTheaterSeat = geConTheaterSeatMapper.selectOne(new LambdaQueryWrapper<GeConTheaterSeat>().last("limit 1"));
        JSONArray totalArrays = JSONArray.parseArray(geConTheaterSeat.getSeat());
        for (int i = 0; i < totalArrays.size(); i++) {
            String toString = totalArrays.get(i).toString();
            JSONObject jsonObject = JSONObject.parseObject(toString);
            String value = jsonObject.getString("value");
            if(selectArr.contains(value)){
                jsonObject.put("status", "1");
            }else {
                jsonObject.put("status", "0");
            }
            totalArrays.set(i,jsonObject);
        }

        result.setOccupancyRate(occupancyRate);
        result.setSeats(totalArrays);
        result.setSelectNums(nums);
        result.setTotalNums(68);

        //各电影投票数量
        PageHelper.startPage(pageNum, pageSize);
        List<TheaterTicketNumsVO> ticketNumsVOS = geConTheaterPlanMapper.getMovieTicketNums();
        result.setTicketNumsVOS(ticketNumsVOS);

        return CommonResult.success("查询成功",result);
    }

    @Override
    public CommonResult<TheaterHomePageNewVO> getTheaterHomePageNew(String openId) {
        TheaterHomePageNewVO theaterHomePageNewVO = new TheaterHomePageNewVO();
        //放映时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
        GeConTheaterTime geConTheaterTime = geConTheaterTimeService.getById(1);
        String formattedTime = geConTheaterTime.getShowTime().format(formatter);

        //本周点映
        TheaterDianYingVO theaterDianYingVO = new TheaterDianYingVO();
        List<Map<String,String>> movies = new ArrayList<>();
        List<TheaterShowVO> theaterDainYingWeek = geConTheaterPlanMapper.getTheaterDainYingWeek();
        //基础信息
        if(theaterDainYingWeek.size()>0){
            theaterDianYingVO.setId(theaterDainYingWeek.get(0).getId());
            theaterDianYingVO.setDate(theaterDainYingWeek.get(0).getDate());
        }
        //电影信息
        for (TheaterShowVO theaterShowVO : theaterDainYingWeek) {
            Map<String,String> map = new HashMap<>();
            map.put("name",theaterShowVO.getName());
            map.put("picture",theaterShowVO.getPicture());
            map.put("movieId",theaterShowVO.getMovieId());
            //判断是否投过
            WxUserTheaterTicket isVote =wxUserTheaterTicketService.isVote(openId,theaterShowVO.getMovieId(),theaterShowVO.getId());
            if(isVote!=null){
                map.put("isVote","1");
            }else {
                map.put("isVote","0");
            }
            movies.add(map);
        }
        theaterDianYingVO.setMovies(movies);
        theaterHomePageNewVO.setTheaterDianYingVO(theaterDianYingVO);

        //本周放映
        List<TheaterShowVO> theaterShowVOS = geConTheaterPlanMapper.getTheaterShowWeek();
        for (TheaterShowVO theaterShowVO : theaterShowVOS) {
            //日期
            try {
                String date = addMinutes(formattedTime, theaterShowVO.getDuration());
                theaterShowVO.setShowTime(formattedTime+" - "+date);
            } catch (ParseException e) {
                break;
            }
            //剩余预约人数
            long num = geConTheaterPlanReserveMapper.getReserveNum(theaterShowVO.getId());
            theaterShowVO.setNum(Math.toIntExact(50 - num));
        }

        //获取今日的点映
        GeConTheaterPlan today = geConTheaterPlanService.lambdaQuery()
                .eq(GeConTheaterPlan::getStartTime, LocalDate.now())  // LocalDate.now() 获取当前日期
                .eq(GeConTheaterPlan::getType, "2")  // "2" 为字符串类型的比较
                .one();

        if(today!=null){
            //获取哪个电影投票最大
            GeConTheaterPlanMovie geConTheaterPlanMovie = geConTheaterPlanMovieMapper.getMax(today.getId());
            TheaterShowVO dianYing = geConTheaterPlanMapper.getDianYing(geConTheaterPlanMovie.getPlanId(),geConTheaterPlanMovie.getMovieId());
            //日期
            try {
                String date = addMinutes(formattedTime, dianYing.getDuration());
                dianYing.setShowTime(formattedTime+" - "+date);
            } catch (ParseException e) {
                System.out.println(e);
            }
            //剩余预约人数
            long num = geConTheaterPlanReserveMapper.getReserveNum(dianYing.getId());
            dianYing.setNum(Math.toIntExact(50 - num));
            theaterShowVOS.add(0, dianYing);
        }
        theaterHomePageNewVO.setTheaterShowVOS(theaterShowVOS);
        return CommonResult.success("查询成功",theaterHomePageNewVO);
    }

    @Override
    public CommonResult getPlanDetails(String id, String movieId) {
        TheaterDetailsVO theaterDetailsVO = new TheaterDetailsVO();
        //放映时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
        GeConTheaterTime geConTheaterTime = geConTheaterTimeService.getById(1);
        String formattedTime = geConTheaterTime.getShowTime().format(formatter);

        GeConTheaterPlan geConTheaterPlan = geConTheaterPlanMapper.selectById(id);
        theaterDetailsVO.setTime(geConTheaterPlan.getStartTime()+" "+formattedTime);
        //电影
        GeConTheaterMovie geConTheaterPlanMovie = geConTheaterMovieMapper.selectById(movieId);
        BeanUtils.copyProperties(geConTheaterPlanMovie,theaterDetailsVO);
        //类型字典
        if(theaterDetailsVO.getType()!=null){
            String typeText = "";
            String[] split = theaterDetailsVO.getType().split(",");
            for (String s : split) {
                String type_movie = geBaseDictService.getTextByCodeAndValue("type_movie", s);
                typeText = typeText + type_movie+"/";

            }
            theaterDetailsVO.setTypeText(typeText.substring(0,typeText.length()-1));
        }
        //演员
        List<GeConTheaterMovieActor> actors = geConTheaterMovieActorMapper.selectList(new LambdaQueryWrapper<GeConTheaterMovieActor>()
                .eq(GeConTheaterMovieActor::getMovieId, movieId));
        theaterDetailsVO.setActors(actors);
        //人数
        //剩余预约人数
        long num = geConTheaterPlanReserveMapper.getReserveNum(id);
        theaterDetailsVO.setRemainNum(50 - num);
        theaterDetailsVO.setUseNum(num);
        return CommonResult.success("查询成功",theaterDetailsVO);
    }
}
